<template>
  <div :ref="'player-' + info.uuid" class="player-main">
    <template v-if="player.id">
      <!-- 标题栏 -->
      <top-bar
        ref="topBar"
        class="player-top-bar"
        :title="info.cameraInfo.name"
        :title-show="titleShow"
        :player="player"
        @remove-player="removePlayer"
        @change-selected="$emit('change-selected')"
      />
      <!-- 工具栏 -->
      <bottom-bar
        v-if="layoutConfig.showToolbar"
        ref="bottomBar"
        class="player-bottom-bar"
        :title-show="titleShow"
        :is-muted="isMuted"
        :is-recording="isRecording"
        :frame="frame"
        :bitrate="bitrate"
        :disabled="toolsDisabled"
        @enter-btn="enterBottomBtn"
        @video-type-change="videoTypeChange"
      />
      <!-- 播放器 -->
      <div
        :id="player.id"
        :ref="player.id"
        class="player-box"
        @dblclick="fullScreen"
        @mousedown.stop="mouseDown"
        @mousemove="mouseMove"
        @mouseup="mouseUp"
      />
      <!-- 播放状态 -->
      <div v-if="statusLabel" class="label-message">
        <div v-html="statusLabel" />
        <el-button
          v-if="again"
          type="text"
          @click="player.connectNow()"
        >
          立即重连
        </el-button>
      </div>
      <!-- 叠加信息 -->
      <template v-if="layoutConfig.showSmart && player.pc && smartList.length">
        <mind-message
          v-for="(item,index) in smartList[0].list"
          :key="index"
          :message="item.message"
          :center="item.center"
          :position="item.position"
          :text-align="item.textAlign"
        />
      </template>
    </template>
  </div>
</template>

<script>
import { uuid } from 'vue-uuid'
import axios from 'axios'
import { iVMSPlayer } from './components/ivms/iVMSPlayer'
import { defaultState } from '@/components/VideoManagement/mixins'
import { BottomBarControl } from './components/ivms/BottomBarMethods'
import TopBar from './components/TopBar'
import BottomBar from './components/BottomBar'
import MindMessage from './components/MindMessage'

export default {
  name: 'PlayerMain',
  components: {
    TopBar,
    BottomBar,
    MindMessage
  },
  mixins: [defaultState],
  props: {
    info: {
      type: Object,
      default: () => {
        const _info = {
          layoutId: uuid.v1(),
          cameraInfo: {},
          replay: {},
          time: 0
        }
        _info.cameraInfo[this.treeNodeKey] = ''
        return _info
      }
    }
  },
  data() {
    return {
      id: '',
      player: { id: '' },
      statusLabel: '',
      control: null,
      isMuted: false,
      isRecording: false,
      frame: '',
      bitrate: '',
      titleShow: true,
      smartList: [],
      again: false,
      toolsDisabled: true,
      isDown: false,
      startPosition: {
        x: 0,
        y: 0
      },
      type: 0
    }
  },
  watch: {
    info: {
      handler: function(val, olVal) {
        if (val.cameraInfo[this.treeNodeKey]) {
          this.playerInit()
        }
      },
      deep: true
    }
  },
  methods: {
    // 鼠标拖动操作
    mouseDown(e) {
      this.isDown = true
      this.startPosition = {
        x: e.pageX,
        y: e.pageY
      }
      this.$emit('change-selected', this.info)
    },
    mouseMove(e) {
      if (this.isDown) {
        const _x = e.pageX - this.startPosition.x
        const _y = e.pageY - this.startPosition.y
        const _z = Math.abs(_x) - Math.abs(_y)
        let type = 0
        if (_z < 0) {
          if (Math.abs(_y > 20)) {
            if (_y > 0) {
              type = 2
            } else if (_y < 0) {
              type = 1
            }
          }
        } else {
          if (Math.abs(_x) > 20) {
            if (_x > 0) {
              type = 4
            } else if (_x < 0) {
              type = 3
            }
          }
        }
        if (type !== 0 && this.type !== type) {
          if (this.layoutSelected.cameraInfo[this.treeNodeKey]) {
            new Promise(resolve => {
              this.ptzControl(0)
              resolve(type)
            }).then(type => {
              this.type = type
              this.ptzControl(type)
            })
          }
        }
      }
    },
    mouseUp(e) {
      this.isDown = false
      this.startPosition = {
        x: 0,
        y: 0
      }
      if (this.layoutSelected.cameraInfo[this.treeNodeKey] && this.type !== 0) {
        this.type = 0
        this.ptzControl(0)
      }
    },
    ptzControl(operation) {
      const url = `${this.layoutConfig.enableHTTPS ? 'https://' : 'http://'}${this.layoutConfig.server.stream.ip}:${this.layoutConfig.server.stream.port}`
      axios.get(`${url}/ivms/ptz`, {
        params: {
          ChanPubId: this.layoutSelected.cameraInfo[this.treeNodeKey],
          PtzType: operation,
          PtzParam: 120,
          AuthorizationId: this.authorizationId
        }
      })
    },
    videoTypeChange(e) {
      document.getElementById(`video-${this.player.id}`).style.objectFit = e
    },
    getSmartList() {
      this.smartList = this.layoutConfig.smartList.filter(item => {
        return item.cameraId === this.info.cameraInfo[this.treeNodeKey]
      })
    },
    playerInit() {
      new Promise(resolve => {
        let flag = false
        if (this.player.id) {
          this.player.destroy()
          this.player = { id: '' }
          // this.removePlayer()
          flag = true
        }
        resolve(flag)
      }).then(flag => {
        setTimeout(() => {
          this.playerStart()
        }, flag ? 500 : 10)
      })
    },
    playerStart() {
      const $this = this
      $this.again = false
      this.toolsDisabled = true
      this.player = new iVMSPlayer({
        vm: $this,
        id: uuid.v1(),
        serverType: 1,
        server: {
          stream: {
            serverIp: this.layoutConfig.server.stream.ip,
            serverPort: this.layoutConfig.server.stream.port
          },
          ws: {
            serverIp: this.layoutConfig.server.ws.ip,
            serverPort: this.layoutConfig.server.ws.port
          }
        }, // 服务器地址  140.249.20.46:8686
        channel: $this.info.cameraInfo[$this.treeNodeKey], // 通道20位编码
        authorization: $this.authorizationId,
        transType: 'udp', // 取流模式，默认udp，值：udp/tcpclient/tcpserver
        maxReconnectTimes: $this.layoutConfig.reconnectTimes, // 最大重连次数，默认6次
        reconnectDuration: $this.layoutConfig.reconnectDuration // 重连间隔 默认5s
      })
      this.$nextTick(() => {
        this.player.on('play', () => {
          const timer = setInterval(() => {
            if ($this.player && $this.player.pc) {
              $this.statusLabel = ''
              $this.again = false
              $this.setBottomBar()
              $this.getSmartList()
              clearInterval(timer)
            }
          }, 1000)
        })
        this.player.on('error', error => {
          console.log(error)
        })
        this.player.on('disconnect', data => {
          $this.again = true
          this.toolsDisabled = true
          this.statusLabel = data['msg'] || '连接被迫断开，请稍后再试或联系管理员'
        })
        this.player.on('reconnect', data => {
          this.toolsDisabled = true
          const { count, time } = data
          if (time === 0) {
            this.statusLabel = `正在连接，请稍后……`
            this.again = false
          } else {
            this.again = true
            this.statusLabel = `<p>第${count}次重连   ${time}秒后进行重连</p>`
          }
        })
        this.player.on('keepStop', () => {
          this.removePlayer()
        })
        this.player.init(this.$refs[this.player.id])
      })
    },
    // 声明设置底部工具条
    setBottomBar() {
      this.control = new BottomBarControl({
        el: this.$refs[this.player.id],
        pc: this.player.pc,
        video: this.player.el,
        title: this.info.cameraInfo.name,
        vm: this
      })
      this.frame = ''
      this.bitrate = ''
      this.control._setNetInformationListener()
      this.control.on('setMsg', (msg) => {
        const { frame, bitrate } = msg
        this.frame = frame
        this.bitrate = bitrate
      })
      this.toolsDisabled = false
    },
    // 底部按钮功能
    enterBottomBtn(e) {
      if (e.method === 'isShowTitle') {
        this.titleShow = !this.titleShow
      } else {
        // 优先执行LayoutItem组件的更改选中方法
        this.$emit('change-selected')
        this.$nextTick(() => {
          // 执行绑定方法
          if (!e.disabled && e.method) {
            try {
              this.control.eval(e.method)
            } catch (e) {
              this.$message.warning('视频未就绪，请稍后再试')
            }
          }
        })
      }
    },
    // 双击全屏
    fullScreen() {
      this.stopCarousel()
      this.enterBottomBtn({
        disabled: false,
        method: 'fullScreen'
      })
    },
    removePlayer() {
      if (this.player.id) {
        this.player.destroy()
        this.player = { id: '' }
      }
      this.stopCarousel()
      const _info = {
        layoutId: this.info.uuid,
        cameraInfo: {},
        replay: {},
        time: 0
      }
      _info.cameraInfo[this.treeNodeKey] = ''
      this.setCameraInfo(_info)
    }
  }
}
</script>

<style scoped lang="scss">
.player-main {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  overflow: hidden;

  .label-message {
    width: 100%;
    height: auto;
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
    color: red;
  }

  .player-top-bar {
    position: absolute;
    left: 0;
    top: -30px;
    z-index: 2;
  }

  .player-bottom-bar {
    position: absolute;
    left: 0;
    bottom: -30px;
    z-index: 2;
  }

  &:hover .player-top-bar {
    top: 0;
  }

  &:hover .player-bottom-bar {
    bottom: 0;
  }

  .player-box {
    width: 100%;
    height: 100%;
    position: relative;
    text-align: center;
    vertical-align: middle;

    video {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
  }
}
</style>
